//
// Copyright (c) 2002-2009 "Neo Technology,"
//     Network Engine for Objects in Lund AB [http://neotechnology.com]
// *
// This file is part of Neo4j.
// 
// Neo4j is free software: you can redistribute it and/or modify
// it under the terms of the GNU Affero General Public License as
// published by the Free Software Foundation, either version 3 of the
// License, or (at your option) any later version.
// 
// This program is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
// GNU Affero General Public License for more details.
// 
// You should have received a copy of the GNU Affero General Public License
// along with this program. If not, see <http://www.gnu.org/licenses/>.
// 
#region Using Directives

using System.Collections.Generic;
using Direction = org.neo4j.graphdb.Direction;
using Node = org.neo4j.graphdb.Node;
using RelationshipType = org.neo4j.graphdb.RelationshipType;
using ReturnableEvaluator = org.neo4j.graphdb.ReturnableEvaluator;
using StopEvaluator = org.neo4j.graphdb.StopEvaluator;

#endregion
namespace org.neo4j.kernel.impl.traversal
{
    ///
    /// <summary> A traverser that traverses the node space breadth-first. Breadth-first means
    /// that it visits all the end-nodes of the current node's relationships before
    /// it visits the end-nodes of those nodes' relationships. This class is package
    /// private: any documentation interesting to a client programmer should reside
    /// in <seealso cref="InternalTraverser"/>. For some implementation documentation, see
    /// <seealso cref="AbstractTraverser"/>.
    ///  </summary>
    /// <seealso cref= "InternalTraverser"> </seealso>
    /// <seealso cref= "AbstractTraverser"> </seealso>
    /// <seealso cref= "DepthFirstTraverser"> </seealso>
    /// 
	internal class BreadthFirstTraverser : AbstractTraverser
	{
        #region Private Variables

        /// <summary>
        /// 
        /// </summary>
        private LinkedList<TraversalPositionImpl> nodeQueue;

        #endregion

        #region Class Constructors

        /// <summary> 
        ///  Creates a BreadthFirstTraverser according the contract of
        /// <seealso cref="AbstractTraverser#AbstractTraverser AbstractTraverser"/>
        ///  </summary>
        internal BreadthFirstTraverser(Node startNode, RelationshipType[] traversableRels, Direction[] traversableDirections, RelationshipType[] preservingRels, Direction[] preservingDirections, StopEvaluator stopEvaluator, ReturnableEvaluator returnableEvaluator, RandomEvaluator randomEvaluator)
            : base(startNode, traversableRels, traversableDirections, preservingRels, preservingDirections, stopEvaluator, returnableEvaluator, randomEvaluator)
        {
        }

        #endregion

        #region Implementations

        /// <summary>
        /// 
        /// </summary>
        /// <param name="position"></param>
        internal override void AddPositionToList(TraversalPositionImpl position)
        {
            this.nodeQueue.AddLast(position);
        }
        /// <summary>
        /// 
        /// </summary>
        /// <returns></returns>
        internal override TraversalPositionImpl GetNextPositionFromList()
        {
            //TODO: Will implement the proper get next position from list later
            //return this.nodeQueue.RemoveFirst();
            return null;
        }
        /// <summary>
        /// 
        /// </summary>
        /// <returns></returns>
        internal override bool ListIsEmpty()
        {
            return this.nodeQueue.Count == 0;
        }
        /// <summary>
        /// 
        /// </summary>
        /// <returns></returns>
        internal sealed override bool TraverseChildrenInNaturalOrder()
        {
            return true;
        }
        /// <summary>
        /// 
        /// </summary>
        internal override void InitializeList()
        {
            this.nodeQueue = new LinkedList<TraversalPositionImpl>();
        }

        #endregion
	}
}